pub authors: Vec<String>,
pub keywords: Vec<String>,
pub license: Option<String>,
+ pub license_file: Option<String>,
pub description: Option<String>, // not markdown
pub readme: Option<String>, // file, not contents
pub homepage: Option<String>, // url
let mut missing = vec![];
macro_rules! lacking {
- ($($field: ident),*) => {{
+ ($( $($field: ident)||* ),*) => {{
$(
- if md.$field.as_ref().map_or(true, |s| s.is_empty()) {
- missing.push(stringify!($field))
+ if $(md.$field.as_ref().map_or(true, |s| s.is_empty()))&&* {
+ $(missing.push(stringify!($field).replace("_", "-"));)*
}
- )*
+ )*
}}
}
- lacking!(description, license)
+ lacking!(description, license || license_file)
if !missing.is_empty() {
let mut things = missing.slice_to(missing.len() - 1).connect(", ");
if !things.is_empty() {
things.push_str(" or ");
}
- things.push_str(*missing.last().unwrap());
+ things.push_str(missing.last().unwrap().as_slice());
try!(shell.warn(
- format!("Warning: manifest has no {things}. \
+ format!("warning: manifest has no {things}. \
See http://doc.crates.io/manifest.html#package-metadata for more info.",
things = things).as_slice()))
}
use std::collections::HashMap;
use std::io::File;
+use std::io::fs::PathExtensions;
use std::os;
use term::color::BLACK;
let manifest = pkg.get_manifest();
let ManifestMetadata {
ref authors, ref description, ref homepage, ref documentation,
- ref keywords, ref readme, ref repository, ref license,
+ ref keywords, ref readme, ref repository, ref license, ref license_file,
} = *manifest.get_metadata();
let readme = match *readme {
Some(ref readme) => {
}
None => None,
};
+ match *license_file {
+ Some(ref file) => {
+ if !pkg.get_root().join(file).exists() {
+ return Err(human(format!("the license file `{}` does not exist",
+ file)))
+ }
+ }
+ None => {}
+ }
registry.publish(&NewCrate {
name: pkg.get_name().to_string(),
vers: pkg.get_version().to_string(),
readme: readme,
repository: repository.clone(),
license: license.clone(),
+ license_file: license_file.clone(),
}, tarball).map_err(|e| {
human(e.to_string())
})
readme: Option<String>,
keywords: Option<Vec<String>>,
license: Option<String>,
+ license_file: Option<String>,
repository: Option<String>,
}
readme: project.readme.clone(),
authors: project.authors.clone(),
license: project.license.clone(),
+ license_file: project.license_file.clone(),
repository: project.repository.clone(),
keywords: project.keywords.clone().unwrap_or(Vec::new()),
};
manifest.add_warning(format!(" For more information, see \
http://doc.crates.io/build-script.html"));
}
+ if project.license_file.is_some() && project.license.is_some() {
+ manifest.add_warning(format!("warning: only one of `license` or \
+ `license-file` is necessary"));
+ }
+
Ok((manifest, nested_paths))
}
}
# This is a string description of the license for this package. Currently
# crates.io will validate the license provided against a whitelist of known
-# license identifiers from http://spdx.org/licenses/. Multiple licenses can
+# license identifiers from http://spdx.org/licenses/. Multiple licenses can
# be separated with a `/`
license = "..."
+
+# If a project is using a nonstandard license, then this key may be specified in
+# lieu of the above key and must point to a file relative to this manifest
+# (similar to the readme key)
+license-file = "..."
```
The [crates.io](https://crates.io) registry will render the description, display
pub readme: Option<String>,
pub keywords: Vec<String>,
pub license: Option<String>,
+ pub license_file: Option<String>,
pub repository: Option<String>,
}
verifying = VERIFYING,
compiling = COMPILING,
dir = p.url()).as_slice())
- .with_stderr("Warning: manifest has no description or license. See \
- http://doc.crates.io/manifest.html#package-metadata for more info."));
+ .with_stderr("\
+warning: manifest has no description, license or license-file. See \
+http://doc.crates.io/manifest.html#package-metadata for more info."));
let p = project("one")
.file("Cargo.toml", r#"
verifying = VERIFYING,
compiling = COMPILING,
dir = p.url()).as_slice())
- .with_stderr("Warning: manifest has no description. See \
- http://doc.crates.io/manifest.html#package-metadata for more info."));
+ .with_stderr("\
+warning: manifest has no description. See \
+http://doc.crates.io/manifest.html#package-metadata for more info."));
let p = project("both")
.file("Cargo.toml", format!(r#"
.env("HOME", Some(home)),
execs().with_status(0));
})
+
+test!(bad_license_file {
+ let p = project("all")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license-file = "foo"
+ description = "bar"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("publish"),
+ execs().with_status(101)
+ .with_stderr("\
+the license file `foo` does not exist"));
+})